看懂 alphaFilter 後,來看另一個 filter: glowFilter
glowFilter 與 Photoshop 混和選項的外光暈 / 內光暈 效果相似
光暈濾鏡 - 在物件內或外套上光暈,效果:
討論兩個部分:
v4
、v5
版本上的差異
若沒特別調整,v4 與 v5 使用 glowFilter 的結果有點不同
解決這個問題,在濾鏡裡加上 padding 的值即可
// PixiJS v5
const glowFilter = new PIXI.filters.GlowFilter();
glowFilter.padding = 4;
v4 濾鏡的 padding 預設值是 4
v5 濾鏡的 padding 預設值是 0
如果沒有向外延伸濾鏡的範圍,濾鏡效果會被切掉
在 v5 說明文件 裡有提到幾個內建的 uniforms:
內建 uniforms 是 PixiJS v4 與 v5 主要差異之一
不會直接操作到,把值印出來後可以看出一些差別:
僅移動兔子:
filterArea 前兩個值不變,後兩個則是兔子座標
outputFrame 有變化的兩個值也是兔子座標
僅旋轉兔子:
原地旋轉時寬高有變化,也影響了 filterArea 的範圍
加了 padding 後,旋轉與移動兔子:
加上 padding 後
旋轉與移動時,座標與寬高改變,但濾鏡範圍沒有變
(操作 padding 值時可能會影響 filterArea 的值)
很多時候會聽到 濾鏡很吃效能!這樣的說法
在看得懂 Shader 的寫法後,實際上有機會辨別濾鏡是否真的很吃效能
Glow Filter src 共有三個檔案:
主要看的是 GlowFilter.js 與 glow.frag
幾個部分:
rgb2hex
與 hex2rgb
的工具import {rgb2hex, hex2rgb} from '@pixi/utils';
一些 GlowFilter 的 Getter
與 Setter
正規表示式
import fragment from './glow.frag';
...
super(vertex, fragment
.replace(/%QUALITY_DIST%/gi, '' + (1 / quality / distance).toFixed(7))
.replace(/%DIST%/gi, '' + distance.toFixed(7)));
這邊看到一些 fragment.replace() 語法
表示會處理 glow.frag 讀入的字串
幾個部分:
const float PI = 3.14159265358979323846264;
在 Shader 裡,沒有內建圓周率常數
constructor(distance = 10, outerStrength = 4, innerStrength = 0, color = 0xffffff, quality = 0.1) {
...
})
預設 distance=10,quality = 0.1:
在 glow.frag 裡取代完之後
%QUALITY_DIST% 是 (1 / quality / distance).toFixed(7),運算完值為"1.0000000"
%DIST% 是 distance.toFixed(7),運算完值為"10.0000000"
將值帶入運算迴圈:
for (float angle = 0.0; angle <= PI * 2.0; angle += %QUALITY_DIST%) {
cosAngle = cos(angle);
sinAngle = sin(angle);
for (float curDistance = 1.0; curDistance <= %DIST%; curDistance++) {
...
}
}
雙迴圈啊,distancs 的大小直接影響到 %QUALITY_DIST%
與 %DIST%
,
而且是每次運算時皆跑大量迴圈
結論: Glow Filter 確實吃效能,尤其是 光暈效果很大 的時候
本系列主題是學習 WebGL
起步時我推薦從 Shadertoy 的教學開始
較熟悉 Shader 的型別與寫法後
可以看看 PixiJS 裡其他濾鏡的寫法,會很有收穫
並且覺得實際寫 Shader 並沒有那麼可怕了
因為進階的 Shadertoy 範例,或是 Shader of the Week 精選
難度真的很高
WebGL 真的是修羅道,感謝分享!
喔喔,先前看過 WebGL 與 Three.js 初探 系列,WebGL 真的很硬!